package com.shigen.demo.interceptor;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.shigen.demo.Enum.HttpStatusCode;
import com.shigen.demo.bean.Result;
import com.shigen.demo.config.ConfigProperty;
import com.shigen.demo.entity.UserInfo;
import com.shigen.demo.util.Common.Redis;
import com.shigen.demo.util.IPUtil;
import com.shigen.demo.util.RedisUtil;
import com.shigen.demo.util.ResponseUtil;
import com.shigen.demo.util.TokenUtil;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

@Slf4j
@Component
public class JwtInterceptor implements HandlerInterceptor {

  @Autowired
  private TokenUtil tokenUtil;
  @Autowired
  private RedisUtil redisUtil;
  @Autowired
  private ConfigProperty configProperty;

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

    if (!configProperty.isNeedAuthod()) {
      log.info("ip:{} URL:{} do not need authed", IPUtil.getIp(request), request.getRequestURI());
      return true;
    }

    if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
      log.info("ip:{} URL:{} option request", IPUtil.getIp(request), request.getRequestURI());
      return true;
    }

    String token = request.getHeader("token");
    if (StrUtil.isBlank(token)) {
      log.info("ip:{} URL: {} has no token", IPUtil.getIp(request), request.getRequestURI());
      UnAuthorised(response);
      return false;
    }
    // 验证token是否过期
    Boolean verify = tokenUtil.verify(token);
    if (!verify) {
      UnAuthorised(response);
      return false;
    }
    // 获得真实的token，是否在redis中
    String userInfo = redisUtil.get(Redis.TOKEN_PREFIX + tokenUtil.getRealToken(token));

    if (StrUtil.isNotEmpty(userInfo)) {
      // 刷新token的有效时长
      refreashToken(token);
      return true;
    }
    UnAuthorised(response);
    return false;
  }

  public void refreashToken(String token) {
    String parseToken = tokenUtil.parseToken(token);
    String tokenKey = Redis.TOKEN_PREFIX + parseToken.substring(0, parseToken.length() - 10);
    Long expire = redisUtil.getExpire(tokenKey, TimeUnit.SECONDS);
    if (expire < configProperty.getTokenLeftTime()) {
      redisUtil.expire(tokenKey, configProperty.getTokenTimeOut(), TimeUnit.SECONDS);
      // 获得该token对应的ID
      String userInfoStr = redisUtil.get(tokenKey);
      UserInfo userInfo = JSON.parseObject(userInfoStr, UserInfo.class);
      String onlineInfoKey = Redis.ONLINE_INFO_PREFIX + userInfo.getUserId();
      redisUtil.expire(onlineInfoKey, configProperty.getTokenTimeOut(), TimeUnit.SECONDS);
    }
  }

  public void UnAuthorised(HttpServletResponse response) {
    try {
      ResponseUtil.responseOut(response, new Result(HttpStatusCode.UNAUTHORIZED));
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}
